iT邦幫忙

2022 iThome 鐵人賽

DAY 28
1
DevOps

Golang X DevOps系列 第 28

Day 28 - Debugger and Fuzzing to Success

  • 分享至 

  • xImage
  •  

結束了嗎?

  • 經過昨天修正完了第一個 Bug
  • 我們要再去 run 一次 go test -fuzz=Fuzz
  • 結果不如我們所想,程式碼仍有會導致錯誤的地方,但明顯跟一開始 UTF-8 錯誤不一樣
  • 上面顯示的錯誤是下面這樣,轉之前是 \xfb ,轉之後便成了虛缺號
 reverse_test.go:17: Before: "\xfb", after: "�"
  • 讓我們來看看 wiki 上的 UTF-8 對照表
  • Bingo! \xfb 不在 UTF-8 的轉譯範圍內,所以會變成虛缺號

Debuggerrrrrrr!

  • 那其實我們可以透過 debugger 來清楚看到變數變化過程
  • Go 最常用的debugger 是 Delve,那我自己是用 VSCode 所以我來教一下怎麼安裝
  • VSCode 介面輸入 Crtl + Shift + P 就可叫出快速指令, 那在上面輸入 Run and Debug,並點到圖中這個
  • 如果沒有裝過的人,右下角都會跳出一個警示,那在這時候按出 Install就完成了

Break and Press Debug

  • 接著我們在檔案內設置斷點,紅色那個點點,
  • 接著按下Function前的執行鍵,他應該會斷在剛剛出現錯誤的地方
  • 這時候鼠標移到最左邊的叉叉小圈圈,並按下 Debug Test(有一隻蟲在上面的)

  • 這時候我們就可以很清楚的在左邊看到變數的變化過程了

想了解更多可以去這裡

Solution

  • 明顯地,我們不會想要讓虛缺號出現在程式裡,那所以我們要透過 utf8.VaildString 去檢測有沒有不合法的 Byte
  • 我們把 Rerverse 改一下

main.go


func Reverse(s string) (string, error) { // 回傳值要加上 error
	if !utf8.ValidString(s) {            // 透過 utf8.VaildString 我們可以檢測不合法的 Byte
		return s, errors.New("input is an invalid UTF-8 byte")
	}
	b := []rune(s)
	for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
		b[i], b[j] = b[j], b[i]
	}
	return string(b), nil               // 回傳記得也要加 nil
}
  • 那把 Reverse 改完了,我們的 MainImport 也要做一下適當的更改,不然參數對不上
import (
	"errors"
	"fmt"
	"unicode/utf8"
)
-----------------------------------------------------------------------
func main() {
	input := "iron man write quick in thirty days"
	rev, reverseError := Reverse(input)          // 增加error參數去接
	doubleRev, doubleReverError := Reverse(rev)
	fmt.Printf("origin: %q\n", input)
	fmt.Printf("reversed: %q\n, err: %v\n", rev, reverseError)         // 把 error 印出來
	fmt.Printf("after reversed twice: %q\n, err: %v\n", doubleRev, doubleReverError)
}

Reverse.go

  • 接下來是 Fuzzing Test 的部分,我們要讓他有錯誤的時候就 return
// 原本的
rev:= Reverse(orig)
doubleRev:= Reverse(rev)
---------------------------------
// 後來的
rev, err1 := Reverse(orig)
if err1 != nil {
	return
	}
doubleRev, err2 := Reverse(rev)
if err2 != nil {
	return
}

Fuzzing to Success

  • 接著我們再來跑一次 Fuzzing test吧
  • 我們記得要加 -fuzztime 的參數,不然除非他遇到錯誤他都不會停
go test -fuzz=Fuzz -fuzztime 1200s
  • 結果會下面這樣
fuzz: elapsed: 0s, gathering baseline coverage: 0/17 completed
fuzz: elapsed: 0s, gathering baseline coverage: 17/17 completed, now fuzzing with 16 workers
fuzz: elapsed: 3s, execs: 698615 (232537/sec), new interesting: 24 (total: 41)
fuzz: elapsed: 6s, execs: 2236680 (513271/sec), new interesting: 25 (total: 42)
fuzz: elapsed: 9s, execs: 3585765 (448219/sec), new interesting: 25 (total: 42)
....................................................................................
fuzz: elapsed: 18m33s, execs: 483007441 (450800/sec), new interesting: 31 (total: 48)
fuzz: elapsed: 18m36s, execs: 484354532 (448469/sec), new interesting: 31 (total: 48)
fuzz: elapsed: 18m39s, execs: 485701835 (448003/sec), new interesting: 31 (total: 48)
fuzz: elapsed: 18m42s, execs: 487038983 (447214/sec), new interesting: 31 (total: 48)
fuzz: elapsed: 18m44s, execs: 487860986 (430396/sec), new interesting: 31 (total: 48)
PASS
ok      go/fuzz 1124.723s
  • 這樣我們的 Fuzzing 就完成了!

上一篇
Day 27 - Introduce to Golang Fuzzing (3)
下一篇
Day29 - Golang 的 Vulnerability Management
系列文
Golang X DevOps30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言